//! 哈希集合(HashSet)示例
//!
//! `HashSet<T>` 是一个包含不重复值的集合，基于 HashMap 实现。

use std::collections::HashSet;

/// 创建哈希集合
pub fn creating_hashsets() {
    // 创建一个新的空 HashSet
    let mut set: HashSet<i32> = HashSet::new();

    // 添加元素
    set.insert(1);
    set.insert(2);
    set.insert(3);
    set.insert(2); // 重复元素不会被插入

    println!("创建哈希集合:");
    println!("set: {:?}", set);

    // 从数组创建 HashSet
    let vec = vec![1, 2, 3, 4, 5, 4, 3, 2, 1];
    let set: HashSet<i32> = vec.into_iter().collect();

    println!("从向量创建:");
    println!("set: {:?}", set);

    // HashSet基本操作示例
    let mut set = HashSet::new();
    set.insert("apple");
    set.insert("banana");
    set.insert("orange");
    // 插入重复元素
    set.insert("orange");
    // 使用debug打印
    print!("{:?}", set);
    // 删除元素
    set.remove("banana");
    // 检查元素是否存在
    if set.contains("banana") {
        println!("Set contains 'banana'");
    } else {
        println!("Set does not contain 'banana'");
    }
    println!("HashSet基本操作结果: {:?}", set);
}

/// HashSet 基本操作
pub fn basic_operations() {
    let mut a: HashSet<i32> = vec![1, 2, 3].into_iter().collect();
    let b: HashSet<i32> = vec![3, 4, 5].into_iter().collect();

    // 查找元素
    println!("基本操作:");
    println!("集合 a 包含 1: {}", a.contains(&1));
    println!("集合 a 包含 4: {}", a.contains(&4));

    // 删除元素
    a.remove(&2);
    println!("删除 2 后的集合 a: {:?}", a);

    // 遍历集合
    println!("遍历集合 b:");
    for x in &b {
        println!("{}", x);
    }

    // 遍历hashset
    let set: HashSet<_> = ["apple", "banana", "orange"].iter().cloned().collect();
    println!("遍历hashset:");
    for item in &set {
        println!("{}", item);
    }
}

/// 集合运算
pub fn set_operations() {
    let a: HashSet<i32> = vec![1, 2, 3].into_iter().collect();
    let b: HashSet<i32> = vec![3, 4, 5].into_iter().collect();

    // 并集
    let union: HashSet<i32> = a.union(&b).cloned().collect();
    println!("并集 a ∪ b: {:?}", union);

    // 交集
    let intersection: HashSet<i32> = a.intersection(&b).cloned().collect();
    println!("交集 a ∩ b: {:?}", intersection);

    // 差集
    let difference: HashSet<i32> = a.difference(&b).cloned().collect();
    println!("差集 a - b: {:?}", difference);

    // 对称差集
    let symmetric_difference: HashSet<i32> = a.symmetric_difference(&b).cloned().collect();
    println!("对称差集 (a ∪ b) - (a ∩ b): {:?}", symmetric_difference);

    // 更多集合运算示例
    let set1: HashSet<_> = [1, 2, 3].iter().cloned().collect();
    let set2: HashSet<_> = [3, 4, 5].iter().cloned().collect();

    // 并集
    let union: HashSet<_> = set1.union(&set2).cloned().collect();
    println!("Union: {:?}", union);

    // 交集
    let intersection: HashSet<_> = set1.intersection(&set2).cloned().collect();
    println!("Intersection: {:?}", intersection);

    // 差集
    let difference: HashSet<_> = set1.difference(&set2).cloned().collect();
    println!("Difference: {:?}", difference);

    // 对称差集
    let symmetric_difference: HashSet<_> = set1.symmetric_difference(&set2).cloned().collect();
    println!("Symmetric Difference: {:?}", symmetric_difference);
}

/// 使用 HashSet 去重
pub fn deduplication() {
    let names = vec!["Alice", "Bob", "Charlie", "Alice", "David", "Bob"];

    let unique_names: HashSet<&str> = names.into_iter().collect();

    println!("去重示例:");
    println!("原始名称: {:?}", vec!["Alice", "Bob", "Charlie", "Alice", "David", "Bob"]);
    println!("唯一名称: {:?}", unique_names);
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_creating_hashsets() {
        creating_hashsets();
    }

    #[test]
    fn test_basic_operations() {
        basic_operations();
    }

    #[test]
    fn test_set_operations() {
        set_operations();
    }

    #[test]
    fn test_deduplication() {
        deduplication();
    }
}
